package com.ocom.payconfig.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.ocom.common.entity.human.EntityPageEnum;
import com.ocom.common.entity.payconfig.EntityMqttDevice;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.company.PageEnumRequest;
import com.ocom.common.request.emqx.GetDeviceArgsRequest;
import com.ocom.common.request.emqx.YhDeviceWorkStatusRequest;
import com.ocom.common.request.payconfig.GetDishesPriceInfoListRequest;
import com.ocom.common.request.payconfig.IotDeviceListRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.vo.emqx.YhDeviceWorkStatusVo;
import com.ocom.common.vo.payconfig.DeviceInfoVo;
import com.ocom.common.vo.payconfig.GetDishesPriceInfoListVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.client.CompanyClientService;
import com.ocom.payconfig.client.EmqxClientService;
import com.ocom.payconfig.dao.IDaoMqttDevice;
import com.ocom.payconfig.service.DishesInfoService;
import com.ocom.payconfig.service.MqttDeviceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


@Service
public class MqttDeviceServiceImpl extends ServiceImpl<IDaoMqttDevice, EntityMqttDevice> implements MqttDeviceService {
    private static final Logger logger = LoggerFactory.getLogger(MqttDeviceServiceImpl.class);
    @Autowired
    private EmqxClientService emqxClientService;

    @Autowired
    private CompanyClientService companyClientService;

    @Autowired
    private DishesInfoService dishesInfoService;

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityMqttDevice> getDeviceListByPoint(Long companyId, List<Integer> points) {
        QueryWrapper<EntityMqttDevice> query = Wrappers.query();
        query.eq("com_id",companyId);
        query.in("point_id",points);
        return this.list(query);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public boolean save(Long companyId, EntityMqttDevice entityMqttDevice) {
        return this.save(entityMqttDevice);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityMqttDevice getByDeviceNo(Long companyId, EntityMqttDevice entityMqttDevice) {
        return this.getOne(Wrappers.lambdaQuery(EntityMqttDevice.class).eq(EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo()));
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE,companyId = "companyId")
    public EntityMqttDevice getByDeviceId(Long companyId, EntityMqttDevice entityMqttDevice) {
        return super.getOne(Wrappers.lambdaQuery(EntityMqttDevice.class).eq(EntityMqttDevice::getMqttDeviceId,entityMqttDevice.getMqttDeviceId()));
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE,companyId = "companyId")
    public EntityMqttDevice selectDevice(Long companyId, EntityMqttDevice entityMqttDevice) {
        return this.getOne(Wrappers.lambdaQuery(EntityMqttDevice.class)
                .eq(ObjectUtil.isNotEmpty(entityMqttDevice.getComId()),EntityMqttDevice::getComId,entityMqttDevice.getComId())
                .eq(ObjectUtil.isNotEmpty(entityMqttDevice.getMqttDeviceId()),EntityMqttDevice::getMqttDeviceId,entityMqttDevice.getMqttDeviceId())
                .eq(ObjectUtil.isNotEmpty(entityMqttDevice.getMqttDeviceNo()),EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo())
                .last("limit 1")
        );
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public boolean update(Long companyId, EntityMqttDevice entityMqttDevice) {
        return this.update(entityMqttDevice,Wrappers.lambdaQuery(EntityMqttDevice.class)
                .eq(EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo())
                .eq(EntityMqttDevice::getComId,entityMqttDevice.getComId())
                .eq(ObjectUtil.isNotEmpty(entityMqttDevice.getMerchId()),EntityMqttDevice::getMerchId,entityMqttDevice.getMerchId())
        );
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public boolean remove(Long companyId, EntityMqttDevice entityMqttDevice) {
        return this.remove(Wrappers.lambdaQuery(EntityMqttDevice.class)
                .eq(EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo())
                .eq(EntityMqttDevice::getMerchId,entityMqttDevice.getMerchId())
                .eq(EntityMqttDevice::getComId,entityMqttDevice.getComId())
        );
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public PageInfo<EntityMqttDevice> page(Long companyId, IotDeviceListRequest request, EntityMqttDevice entityMqttDevice) {
        PageHelper.startPage(request.getPage(), request.getSize());
        List<EntityMqttDevice>  deviceList = this.list(Wrappers.lambdaQuery(EntityMqttDevice.class)
                .eq(EntityMqttDevice::getComId,entityMqttDevice.getComId())
                .eq(EntityMqttDevice::getMerchId,entityMqttDevice.getMerchId())
                .like(ObjectUtil.isNotEmpty(entityMqttDevice.getMqttDeviceNo()),EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo())
                .orderByDesc(EntityMqttDevice::getMqttDeviceNo));
        return  new PageInfo<>(deviceList);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.SLAVE)
    public EntityMqttDevice getDeviceListByDeviceNo(Long companyId, String deviceNo) {
        QueryWrapper<EntityMqttDevice> query = Wrappers.query();
        query.eq("mqtt_device_no",deviceNo);
        return this.getOne(query);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public void updateByDeviceNo(Long companyId, EntityMqttDevice entityMqttDevice) {
//        this.updateById(entityMqttDevice);
        this.update(entityMqttDevice,Wrappers.lambdaQuery(EntityMqttDevice.class).eq(EntityMqttDevice::getMqttDeviceNo,entityMqttDevice.getMqttDeviceNo()));
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public void updateByDeviceNoOnlineState(Long companyId, List<String> deviceNos) {
        if(deviceNos==null || deviceNos.size()==0){
            UpdateWrapper<EntityMqttDevice> updateWrapper =new UpdateWrapper<>();
            updateWrapper.set("online",0);
            updateWrapper.gt("com_id",0);
            this.update(updateWrapper);
            return;
        }

        UpdateWrapper<EntityMqttDevice> updateWrapper =new UpdateWrapper<>();
        updateWrapper.set("online",1);
        updateWrapper.set("comm_time",new Date());
        updateWrapper.gt("com_id",0);
        updateWrapper.in("mqtt_device_no",deviceNos);
        this.update(updateWrapper);

        UpdateWrapper<EntityMqttDevice> updateWrapper1 =new UpdateWrapper<>();
        updateWrapper1.set("online",0);
        updateWrapper1.set("comm_time",new Date());
        updateWrapper1.gt("com_id",0);
        updateWrapper1.ne("mqtt_device_no",deviceNos);
        this.update(updateWrapper);
    }

    @Override
    public List<EntityMqttDevice> getDeviceArgs(GetDeviceArgsRequest request) {
        List<String> strModelList = new ArrayList<>();
        List<Integer> strClassList = new ArrayList<>();
        List<EntityMqttDevice> deviceList = this.getDeviceListByPoint(request.getComId(), Lists.newArrayList(request.getPointId()));
//        logger.info("device_list_001：【{}】",JSON.toJSONString(deviceList));
        for (int i=0;i< deviceList.size();i++){
            EntityMqttDevice entityMqttDevice = deviceList.get(i);
            if(3 == entityMqttDevice.getMqttDeviceType()){
                continue;
            }
            YhDeviceWorkStatusRequest deviceWorkStatusRequest = new YhDeviceWorkStatusRequest();
            deviceWorkStatusRequest.setStatus(entityMqttDevice.getDeviceStatus());
            deviceWorkStatusRequest.setSubRun(entityMqttDevice.getSubRun());
            deviceWorkStatusRequest.setSubNum(entityMqttDevice.getSubNum());

            Result<YhDeviceWorkStatusVo> resultA= this.emqxClientService.yhDeviceWorkStatus(deviceWorkStatusRequest);
            YhDeviceWorkStatusVo yhDeviceWorkStatusVo = resultA.getData();
            if(!entityMqttDevice.getOnline()){
                deviceList.get(i).setDeviceStatus(6);
                strModelList.add(entityMqttDevice.getMqttDeviceModel());
                strClassList.add(entityMqttDevice.getDishesClassId());
//                logger.info("根据消费点返回物联网设备参数_-1：【{}】",JSON.toJSONString(entityMqttDevice));
                continue;
            }
            if(!entityMqttDevice.getErrStatus().equals(0)){
                deviceList.get(i).setDeviceStatus(2);
                strModelList.add(entityMqttDevice.getMqttDeviceModel());
                strClassList.add(entityMqttDevice.getDishesClassId());
//                logger.info("根据消费点返回物联网设备参数_0：【{}】",JSON.toJSONString(entityMqttDevice));
                continue;
            }

            if(!entityMqttDevice.getOrderStatus().equals(0)){
                YhDeviceWorkStatusRequest yhDeviceWorkStatusRequest = new YhDeviceWorkStatusRequest();
                yhDeviceWorkStatusRequest.setStatus(entityMqttDevice.getDeviceStatus());
                yhDeviceWorkStatusRequest.setSubRun(entityMqttDevice.getSubRun());
                yhDeviceWorkStatusRequest.setSubNum(entityMqttDevice.getSubNum());
                Result<YhDeviceWorkStatusVo> resultB = this.emqxClientService.yhDeviceWorkStatus(yhDeviceWorkStatusRequest);
                deviceList.get(i).setDeviceStatus(5);
                if(resultB.getCode().equals(200)){
                    if(resultB.getData().getOrdered().equals(1)){
                        deviceList.get(i).setDeviceStatus(7);
                    }
                }

                strModelList.add(entityMqttDevice.getMqttDeviceModel());
                strClassList.add(entityMqttDevice.getDishesClassId());
//                logger.info("根据消费点返回物联网设备参数_1：【{}】",JSON.toJSONString(entityMqttDevice));
                continue;
            }else{
                YhDeviceWorkStatusRequest yhDeviceWorkStatusRequest = new YhDeviceWorkStatusRequest();
                yhDeviceWorkStatusRequest.setStatus(entityMqttDevice.getDeviceStatus());
                yhDeviceWorkStatusRequest.setSubRun(entityMqttDevice.getSubRun());
                yhDeviceWorkStatusRequest.setSubNum(entityMqttDevice.getSubNum());
                Result<YhDeviceWorkStatusVo> resultC= this.emqxClientService.yhDeviceWorkStatus(yhDeviceWorkStatusRequest);
                if(resultC.getCode().equals(200)){
                    if(resultC.getData().getRunState().equals(1)){
                        deviceList.get(i).setDeviceStatus(1);
                        strModelList.add(entityMqttDevice.getMqttDeviceModel());
                        strClassList.add(entityMqttDevice.getDishesClassId());
//                        logger.info("根据消费点返回物联网设备参数_5：【{}】",JSON.toJSONString(entityMqttDevice));
                        continue;
                    }
                }
            }
            if(!yhDeviceWorkStatusVo.getOrdered().equals(0)){
                if(1 == yhDeviceWorkStatusVo.getOrdered()){
                    deviceList.get(i).setDeviceStatus(5);
                    strModelList.add(entityMqttDevice.getMqttDeviceModel());
                    strClassList.add(entityMqttDevice.getDishesClassId());
//                    logger.info("根据消费点返回物联网设备参数_3：【{}】",JSON.toJSONString(entityMqttDevice));
                    continue;
                }
                if(1 == yhDeviceWorkStatusVo.getRunState()){
                    deviceList.get(i).setDeviceStatus(1);
                    strModelList.add(entityMqttDevice.getMqttDeviceModel());
                    strClassList.add(entityMqttDevice.getDishesClassId());
//                    logger.info("根据消费点返回物联网设备参数_4：【{}】",JSON.toJSONString(entityMqttDevice));
                    continue;
                }

            }

            if(!entityMqttDevice.getMerchId().equals(request.getMerchId())){
                deviceList.get(i).setDeviceStatus(3);
            }else{
//                logger.info("2============,{}", deviceList.get(i).getDeviceStatus());
                deviceList.get(i).setDeviceStatus(0);
                strModelList.add(entityMqttDevice.getMqttDeviceModel());
                strClassList.add(entityMqttDevice.getDishesClassId());
            }

        }

        //
        PageEnumRequest pageEnumRequest = new PageEnumRequest();
        pageEnumRequest.setModels(strModelList);
        pageEnumRequest.setType("mqtt_device_model_");
//        logger.info("获取字段配置_002:参数：【{}】",JSON.toJSONString(pageEnumRequest));
        Result<List<EntityPageEnum>> entityPageEnumResult = this.companyClientService.getPageEnumByModel(pageEnumRequest);
//        logger.info("获取字段配置_003:返回：【{}】",JSON.toJSONString(entityPageEnumResult));
        GetDishesPriceInfoListRequest getDishesPriceInfoListRequest = new GetDishesPriceInfoListRequest();
        getDishesPriceInfoListRequest.setMerchId(request.getMerchId());
        getDishesPriceInfoListRequest.setComId(request.getComId());
        getDishesPriceInfoListRequest.setStrClass(strClassList);
        List<GetDishesPriceInfoListVo> getDishesPriceInfoList = this.dishesInfoService.getDishesPriceInfoList(getDishesPriceInfoListRequest.getComId(),getDishesPriceInfoListRequest);
        logger.info("getDishesPriceInfoList_004:【{}】返回：【{}】",JSON.toJSONString(getDishesPriceInfoListRequest),JSON.toJSONString(getDishesPriceInfoList));
        for (EntityMqttDevice entityMqttDevice: deviceList){
            for (GetDishesPriceInfoListVo getDishesPriceInfoListVo:getDishesPriceInfoList){

//                logger.info("价格---{}-{}",getDishesPriceInfoListVo.getDishesClassId().toString(),entityMqttDevice.getDishesClassId().toString());
                if(getDishesPriceInfoListVo.getDishesClassId().equals(entityMqttDevice.getDishesClassId())){
//                    logger.info("debug:---1");
                    for (EntityPageEnum entityPageEnum:entityPageEnumResult.getData()){
                        if(entityPageEnum.getTip().equals(entityMqttDevice.getMqttDeviceModel())){
                            if(entityPageEnum.getVal().contains(getDishesPriceInfoListVo.getDishesCode())){
                                if(ObjectUtil.isEmpty(entityMqttDevice.getDishesList()) || ObjectUtil.isEmpty(entityMqttDevice.getDishesList().get(getDishesPriceInfoListVo.getDishesCode()))){
                                    if(ObjectUtil.isEmpty(entityMqttDevice.getDishesList())){
                                        entityMqttDevice.setDishesList(new HashMap<>());
                                    }
                                    entityMqttDevice.getDishesList().put(getDishesPriceInfoListVo.getDishesCode(),getDishesPriceInfoListVo);
                                }else{
                                    entityMqttDevice.getDishesList().get(getDishesPriceInfoListVo.getDishesCode()).setPriceMode(getDishesPriceInfoListVo.getPriceMode());
                                    entityMqttDevice.getDishesList().get(getDishesPriceInfoListVo.getDishesCode()).setPrice(getDishesPriceInfoListVo.getPrice());
                                }
                            }
                        }
                    }
                }
            }

            if(ObjectUtil.isEmpty(entityMqttDevice.getDishesList())){
                entityMqttDevice.setDeviceStatus(4);
            }
        }
//        logger.info("deviceList_005:返回：【{}】",JSON.toJSONString(deviceList));
        return deviceList;
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public Integer getMaxOrderId(Long companyId) {
        QueryWrapper<EntityMqttDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("Max(`order_id`) as order_id");
        List<Map<String,Object>> results = listMaps(queryWrapper);
        return Optional.ofNullable(results.get(0))
                .map(map -> Integer.valueOf(map.get("order_id").toString()))
                .orElse(0);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyID")
    @Override
    public DeviceInfoVo selectPointId(Long companyID, String machno) {
        return this.baseMapper.selectPointId(machno,companyID);
    }
}
